import java.util.concurrent.atomic.AtomicBoolean;


public class CPUKnTest {

    public static void main(String[] args) {
        if (args.length != 2) {
            System.out.println("Usage: java CpuCoreControl <core> <usage>");
            System.out.println("Example: java CpuCoreControl 0 50 (to use core 0 at 50% usage)");
            return;
        }

        int core = Integer.parseInt(args[0]); // 目标核心编号
        int usage = Integer.parseInt(args[1]); // 目标占用率

        if (core < 0 || core >= Runtime.getRuntime().availableProcessors()) {
            System.out.println("Invalid core number. Available cores: 0 to " + (Runtime.getRuntime().availableProcessors() - 1));
            return;
        }

        if (usage < 0 || usage > 100) {
            System.out.println("Invalid usage. Usage must be between 0 and 100.");
            return;
        }

        // 启动控制线程
        AtomicBoolean running = new AtomicBoolean(true);
        Thread controlThread = new Thread(new CpuTask(core, usage, running));
        controlThread.start();

        // 等待用户输入以退出
        System.out.println("Running on core " + core + " with " + usage + "% usage. Press Enter to exit.");
        try {
            System.in.read();
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 停止控制线程
        running.set(false);
        try {
            controlThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    static class CpuTask implements Runnable {
        private final int core;
        private final int usage;
        private final AtomicBoolean running;

        public CpuTask(int core, int usage, AtomicBoolean running) {
            this.core = core;
            this.usage = usage;
            this.running = running;
        }

        @Override
        public void run() {
            // 绑定线程到指定的 CPU 核心
            bindToCore(core);

            // 计算 busyTime 和 idleTime
            long busyTime = usage * 10_000L; // 10 毫秒的倍数
            long idleTime = (100 - usage) * 10_000L;

            while (running.get()) {
                // 计算任务：占用 CPU
                long startTime = System.nanoTime();
                while ((System.nanoTime() - startTime) < busyTime) {
                    // 空循环，占用 CPU
                }

                // 休眠：释放 CPU
                try {
                    Thread.sleep(idleTime / 1_000_000, (int) (idleTime % 1_000_000)); // 纳秒级休眠
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        private void bindToCore(int core) {
            try {
                // 使用操作系统命令绑定线程到指定的 CPU 核心
                String os = System.getProperty("os.name").toLowerCase();
                if (os.contains("linux")) {
                    // Linux 使用 taskset
                    Process process = Runtime.getRuntime().exec("taskset -cp " + core + " " + ProcessHandle.current().pid());
                    process.waitFor();
                } else if (os.contains("win")) {
                    // Windows 使用 PowerShell
                    Process process = Runtime.getRuntime().exec("powershell -Command \"$Process = Get-Process -Id " + ProcessHandle.current().pid() + "; $Process.ProcessorAffinity = " + (1 << core) + "\"");
                    process.waitFor();
                } else {
                    System.out.println("Unsupported OS: " + os);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
